<?php

namespace addons\booking\library\order;

use addons\booking\model\House;
use addons\booking\model\Coupon;
use addons\booking\model\OrderCalendar;
use addons\booking\model\Calendar;
use addons\booking\model\UserCoupon;
use addons\booking\model\Lodgers;
use addons\booking\model\Order;
use think\Db;

//房间订单整合参数
class OrderHouse implements orderInterface
{
    /**
     * 房间订单的生成
     *
     * @param [type] $orderInfo 订单信息
     * @param [type] $param 参数值
     * @return Object
     */
    public function planOrder($orderInfo, $param)
    {
        $userCoupon = null;
        $user_id = $param['user_id'];
        $source_id = $param['source_id'];
        $orderInfo['source_id'] = $param['source_id'];

        //校验领取和是否可使用
        if ($param['user_coupon_id']) {
            $userCouponModel = new UserCoupon();
            $userCoupon = $userCouponModel->checkUserOrUse($param['user_coupon_id'], $user_id);
            $orderInfo['user_coupon_id'] = $param['user_coupon_id'];
        }

        $house = House::getDetail($source_id);
        if (empty($house)) {
            throw new \Exception("房间不存在或已下架");
        }

        //寻找日期范围是否有被预定
        if (OrderCalendar::isHasBooked($source_id, $param['start_time'], $param['end_time'])) {
            throw new \Exception('此时间区域未有房间可预定');
        }

        $lodgers = Lodgers::where('user_id', $user_id)->where('id', 'in', $param['lodger_ids'])->select();
        //校验住客信息
        if ($param['nums'] != count($lodgers)) {
            throw new \Exception('住客信息不匹配');
        }

        //校验同一入住时间，是否有预订有房
        foreach ($lodgers as $item) {
            $item['id'] = (int)$item['id'];
            $hasCheckin = Order::where("FIND_IN_SET('{$item['id']}',lodgers_ids)")->where(function ($query) use ($param) {

                $query->where(function ($q) use ($param) {
                    $q->where('checkin_time', '>=', $param['start_time'])->where('leave_time', '<', $param['start_time']);
                })->whereOr(function ($q) use ($param) {
                    $q->where('checkin_time', '<', $param['end_time'])->where('leave_time', '>=', $param['end_time']);
                })->whereOr(function ($q) use ($param) {
                    $q->where('checkin_time', '>=', $param['start_time'])->where('leave_time', '<', $param['end_time']);
                });
            })->where('status', 'IN', ['created', 'paid', 'toshopay', 'checkined'])->count();

            if ($hasCheckin > 0) {
                $s_t = date('Y-m-d', $param['start_time']);
                $e_t = date('Y-m-d', $param['end_time']);
                throw new \Exception("{$item['name']},于{$s_t}至{$e_t}之间已有订单信息，无法重复提交！");
            }
        }

        $orderInfo['lodgers_ids'] = join(',', $param['lodger_ids']);
        $orderInfo['params']['lodgers'] = $lodgers;
        $orderInfo['status'] = 'created';

        //到店付
        if ($house['to_shop_pay'] == 1 || $param['platform'] == 'baidu') {
            $orderInfo['status'] = 'toshopay';
        }

        $orderInfo['checkin_time'] = $param['start_time'];
        $orderInfo['leave_time'] = $param['end_time'];
        //去匹配日历价格
        Calendar::calculate($source_id, $house['price'], $param['start_time'], $param['end_time'], $orderInfo);

        if (!empty($userCoupon)) {
            //校验优惠券
            $couponModel = new Coupon();
            $coupon = $couponModel->getCoupon($userCoupon['coupon_id'])
                ->checkCoupon()
                ->checkOpen()
                ->checkUseTime($userCoupon['createtime'])
                ->checkConditionHouse($house, $user_id, $orderInfo);
            //计算价格
            list($new_money, $coupon_money) = $coupon->doBuy($orderInfo['amount']);
            $orderInfo['amount'] = $new_money;
            $orderInfo['coupon_amount'] = $coupon_money;
        }

        $order = null;
        // 启动事务
        Db::startTrans();
        try {
            //保存订单信息
            $model = new Order();
            $model->save($orderInfo);
            $order = [
                'id'     => $model->getData('id'),
                'amount' => $model->getData('amount'),
                'status' => $orderInfo['status']
            ];
            //房间预订日历记录
            OrderCalendar::addCalendar($param['user_id'], $param['source_id'], $orderInfo['orderid'], $param['start_time'], $param['end_time']);
            //优惠券已使用
            if (!empty($userCoupon)) {
                $userCoupon->save(['is_used' => 2]);
            }
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw new \Exception($e->getMessage());
        }
        return $order;
    }
}
